home *** CD-ROM | disk | FTP | other *** search
- /*
- * dayserv.c
- *
- * server for tcp daytime service (Amiga® format)
- *
- * adapted from "UNIX Network Programming, Vol.1, 2nd Edition" by W. Richard Stevens
- * for Amiga® OS with AmiTCP 4.x compatible network stacks
- *
- * important changes:
- * · returns a "seconds.microseconds" format, not the unix standard format
- *
- * should work with any compiler:
- * · link additional startup routine "startup.c" for Maxon C/C++ only
- * · uses (small & fast) external routine SPrintF for Maxon C/C++ only
- */
-
- #include <pragma/exec_lib.h>
- #include <pragma/dos_lib.h>
- #include <pragma/intuition_lib.h>
- #include <pragma/socket_lib.h>
- #include <sys/socket.h>
- #include <string.h>
-
-
- #define DAYTIMEPORT 13
- #define LISTENQUEUE 5 /* this is a table entry - "5" means the predefined TCP/IP queue count ! */
-
- #ifdef __MAXON__
- #define vsprintf(a,b,c) SPrintF(b,c,a)
- #else
- #include <stdio.h>
- #endif
-
-
- struct Library *SocketBase = NULL, *IntuitionBase = NULL;
-
-
- /* external assembler function */
- #ifdef __MAXON__
- void SPrintF(register __a0 STRPTR fmtstring, register __a1 APTR data, register __a3 UBYTE *buffer);
- #endif
-
-
- /* resource handling */
- BOOL openLib(void)
- {
- BOOL rw = FALSE;
-
- SocketBase = OpenLibrary(SOCKETNAME, 4U);
- IntuitionBase = OpenLibrary("intuition.library", 37U);
-
- if(SocketBase && IntuitionBase)
- {
- rw = TRUE;
- }
-
- return(rw);
- }
-
- void closeLib(void)
- {
- CloseLibrary(IntuitionBase);
- IntuitionBase = NULL;
-
- CloseLibrary(SocketBase);
- SocketBase = NULL;
- }
-
-
- /* main function */
- LONG main(LONG argc, APTR argv)
- {
- struct RDArgs *rdargs;
- STRPTR tmpl = "PORT/N";
- LONG arg[1] = {0L};
- LONG rw;
- int serviceport = DAYTIMEPORT;
-
- /* shell only - this is a learning demo */
- if(argc)
- {
- /* get port number - usually 13 is already used */
- rdargs = ReadArgs(tmpl, arg, NULL);
- if(rdargs)
- {
- serviceport = arg[0] ? *((LONG *) arg[0]) : serviceport;
- }
-
- /* open libraries */
- if(openLib())
- {
- long listenfd, connfd;
- struct sockaddr_in servaddr;
-
- /* create listener socket */
- listenfd = socket(AF_INET, SOCK_STREAM, 0L);
- if(listenfd >= 0L)
- {
- /* specify service and interface */
- memset(&servaddr, 0L, sizeof(struct sockaddr_in));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(serviceport);
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* sin_addr == s_addr */
-
- /* add our server to the port... */
- if(bind(listenfd, (const struct sockaddr *) &servaddr, sizeof(servaddr)) >= 0L)
- {
- /* ...and start listening for requests */
- if(listen(listenfd, LISTENQUEUE) >= 0L)
- {
- /* there is no normal exit from an endless loop, so RETURN_OK is never used */
- for(;;)
- {
- /* standard for()-loop emergency break */
- if(CheckSignal(SIGBREAKF_CTRL_C))
- {
- PutStr("^C -- user break\n");
- rw = RETURN_WARN;
- break;
- }
-
- /* serve client - accept() has a ctrl_c handling itself */
- connfd = accept(listenfd, NULL, NULL);
- if(connfd >= 0L)
- {
- char buf[20];
- ULONG c[2];
-
- CurrentTime(&(c[0]), &(c[1]));
- vsprintf(buf, "%10ld.%06ld\r\n", c);
-
- /* return timeval format (seconds.microseconds) */
- send(connfd, buf, strlen(buf), 0L);
-
- /* the server closes the client connection */
- CloseSocket(connfd);
- }
- else
- {
- Printf("Error code %ld while receiving request\n", connfd);
- }
- }/* for() */
- }
- else
- {
- Printf("Could not start server on port %ld\n", serviceport);
- rw = RETURN_FAIL;
- }
- }
- else
- {
- Printf("Could not reserve port %ld\n", serviceport);
- rw = RETURN_FAIL;
- }
- }
- else
- {
- Printf("Error code %ld while opening network socket\n", listenfd);
- rw = RETURN_FAIL;
- }
-
- closeLib();
- }
- else
- {
- Printf( "Error opening \"%s\" version %ld\n"
- "You must start AmiTCP 4.x, or a compatible TCP/IP stack\n",
- SOCKETNAME, 4L);
-
- rw = RETURN_FAIL;
- }
-
- FreeArgs(rdargs);
- }
-
- return(rw);
- }
-